The development of the EDVAC computer system of 1948 is often cited as the beginning of the computer era. Since that time, computer systems have evolved into extremely sophisticated devices, and computer systems may be found in many different settings. Computer systems typically include a combination of hardware, such as semiconductors and circuit boards, and software, also known as computer programs. As advances in semiconductor processing and computer architecture push the performance of the computer hardware higher, more sophisticated and complex computer software has evolved to take advantage of the higher performance of the hardware, resulting in computer systems today that are much more powerful than just a few years ago.
As the sophistication and complexity of computer software increase, the more difficult the software is to debug. Bugs are problems, faults, or errors in a computer program. Locating, analyzing, and correcting suspected faults in a computer program is a process known as “debugging.” Typically, a programmer uses another computer program commonly known as a “debugger” to debug a program under development.
Conventional debuggers typically support two primary operations to assist a computer programmer. A first operation supported by conventional debuggers is a “step” function, which permits a computer programmer to process instructions (also known as “statements”) in a computer program one-by-one and see the results upon completion of each instruction. While the step operation provides a programmer with a large amount of information about a program during its execution, stepping through hundreds or thousands of program instructions can be extremely tedious and time consuming, and may require a programmer to step through many program instructions that are known to be error-free before a set of instructions to be analyzed is executed.
To address this difficulty, a second operation supported by conventional debuggers is a breakpoint operation, which permits a computer programmer to identify with a breakpoint a precise instruction for which it is desired to halt execution of a computer program during execution. As a result, when a computer program is executed by a debugger, the program executes in a normal fashion until a breakpoint is reached. The breakpoint then causes an interrupt, which stops execution of the program and gives control to the debugger, which displays the results of the program and/or the state of the computer system to the programmer for analysis.
Typically, step operations and breakpoints are used together to simplify the debugging process. Specifically, a common debugging operation is to set a breakpoint at the beginning of a desired set of instructions to be analyzed and then begin executing the program. When the breakpoint is reached, the debugger halts the program, and the programmer then steps through the desired set of instructions line-by-line using the step operation. Consequently, a programmer is able to more quickly isolate and analyze a particular set of instructions without having to step through irrelevant portions of a computer program.
Unfortunately, a breakpoint can cause unrecoverable system hangs when the code encountering the breakpoint is protected by a hardware synchronization mechanism (HSM) that enforces atomic update of a storage location. Examples of hardware synchronization mechanisms are the PowerPC larx/stcx (load and reserve/store conditional) instruction forms, specifically the lwarx/stwcx (word-aligned) and ldarx/stdcx (double-word-aligned) forms, and the Intel Itanium lock instruction prefix. Since hardware synchronization mechanisms require uninterrupted code flow during their execution in order to effect the storage protection they are designed to perform, when an interrupt is issued to service a breakpoint within a hardware synchronization mechanism code range, the hardware reservation is lost or invalidated by the hardware synchronization mechanism, and a retry is required, causing an endless loop within the code range.
Without a better way to handle breakpoints, developers will continue to experience difficulty when debugging programs that use hardware synchronization mechanisms. Although the aforementioned problems have been described in the context of hardware synchronization mechanisms, they may occur in the context of any atomic operation synchronization code ranges.